
import 'dart:async';
import 'dart:math';

import 'package:aqua_plunge/http/app_manager.dart';
import 'package:aqua_plunge/model/Author.dart';
import 'package:aqua_plunge/model/Creation.dart';
import 'package:aqua_plunge/model/media.dart';
import 'package:aqua_plunge/services/database_service.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:video_player/video_player.dart';

class DatabaseController extends GetxController{

  var creations = <Creation>[].obs;
  var mineCreations = <Creation>[].obs;
  var favoritesCreations = <Creation>[].obs;
  var mediaList = <Media>[].obs;
  var authorList = <Author>[].obs;


  var homeCreation = Creation().obs;
  var homeAuthor = Author().obs;
  var authors = <String,Author>{}.obs;
  var imageRatios = <int,double>{}.obs;

  var videoIndex = 0.obs;
  var videoControllers = <VideoPlayerController>[].obs;

  final DatabaseService _databaseService = DatabaseService.instance;

  @override
  void onInit(){
    super.onInit();
    initLoadDatas();
  }

  initLoadDatas() async{
    try{

      creations.value = await _databaseService.getCreationsExcludeBlock();
      homeCreation.value =  creations.isEmpty ? Creation(userId: 0) :creations[Random().nextInt(creations.length)];
      favoritesCreations.value = await _databaseService.getFavoritesCreationList();
      mediaList.value = await _databaseService.getMediaListExcludeBlock();
      authorList.value = (await _databaseService.getAuthorList())!;
      getimagesRatios();

      for(var item in authorList){
        if(homeCreation.value.userId == int.parse(item.userId!)){
          homeAuthor.value = item;
        }
        authors[item.userId!] = item;
      }
      videoControllers.value = List.generate(mediaList.length, (index) =>
          VideoPlayerController.networkUrl(Uri.parse(mediaList[index].mediaUrl??'')));
    }catch(error){
      debugPrint(error.toString());
    }
  }

  Future<void> fetchCreationData() async{
    try{
      creations.value = await _databaseService.getCreationsExcludeBlock();
    }catch(error){
      debugPrint(error.toString());
    }
  }

  Future<void> fetchFavoriteData() async{
    try{
      favoritesCreations.value = await _databaseService.getFavoritesCreationList();
    }catch(error){
      debugPrint(error.toString());
    }
  }
  
  Future<void> fetchMineData() async{
    try{
      mineCreations.value = await _databaseService.getMineCreationList(int.parse(AppManager.getUserInfo().userId!));
    }catch(error){
      debugPrint(error.toString());
    }
  }

  Future<void> fetchMediaData() async{
    try{
      mediaList.value = await _databaseService.getMediaListExcludeBlock();
      videoControllers.value = List.generate(mediaList.length, (index) =>
          VideoPlayerController.networkUrl(Uri.parse(mediaList[index].mediaUrl??'')));
    }catch(error){
      debugPrint(error.toString());
    }
  }

  setVideoIndex(int index){
    videoIndex.value = index;
  }

  globalMediaPause(){
    videoControllers[videoIndex.value].pause();
  }

  globalMediaPlay(){
    debugPrint('===============play=====${videoIndex.value}');
    videoControllers[videoIndex.value].play();
  }

  Future<void> fetchAuthorData() async{
    try{
       authorList.value = (await _databaseService.getAuthorList())!;
    }catch(error){
      debugPrint(error.toString());
    }
  }

  Future<Author> getAuthorByUserId(String userId) async{
    if(authors.containsKey(userId)){
      return authors[userId]!;
    }
    Author author = await _databaseService.getAuthorById(int.parse(userId));
    authors[userId] = author;
    return author;
  }

  updateCreationFavoriteByPostId(int postid,bool favorite){
    try{
      homeCreation.value.like = favorite?1:0;
      _databaseService.updateCreationLike(postid,favorite?1:0);
      fetchCreationData();
      fetchFavoriteData();
    }catch(error){
      debugPrint(error.toString());
    }
  }


  Future<double> getImageAspectRatio(String path) async {

    final image = Image(image: AssetImage(path));
    final completer = Completer<ImageInfo>();
    final ImageStream stream = image.image.resolve(const ImageConfiguration());

    stream.addListener(ImageStreamListener((ImageInfo info, bool synchronousCall) {
      completer.complete(info);
    }));
    final ImageInfo imageInfo = await completer.future;
    // 计算宽高比
    final width = imageInfo.image.width.toDouble();
    final height = imageInfo.image.height.toDouble();
    return width / height; // 返回宽高比
  }


  getimagesRatios() async{
    for(var item in creations){
      imageRatios[item.postId!] = await getImageAspectRatio(item.cover!);
    }
  }

}